import Spreadsheet, { buildMenuItem, xy2expr } from '@yuto/x-spreadsheet'
import { stocks } from './TableStore'
import './index.less'

import zhCN from '../zh-cn'
import { SheetHelper } from './renders'
import { CustomDataProxy } from './CustomDataProxy'
import { getGuid } from '../../utils/getDefaultValue'
import helper from '../../../../x-spreadsheet/src/core/helper'

Spreadsheet.locale('zh-cn', zhCN)

var numbers = [
  '日',
  '一',
  '二',
  '三',
  '四',
  '五',
  '六'
]

const menuItems = [
  // { key: 'new-bill', title: () => '新增交货' },
  { key: 'insert-up-row', title: () => '插入上一行' },
  { key: 'insert-down-row', title: () => '插入下一行' },
  { key: 'delete-row', title: () => '删除选中行' }
]

function buildMenu () {
  return menuItems.map(it => buildMenuItem.call(this, it))
}

class CustomSpreadsheet extends Spreadsheet {
  constructor (selectors, options = {
    styles: [
      {
        bgcolor: '#f0f0f0'
      }
    ]
  }) {
    super(selectors, options)
    this.editable = options.editable
    console.log(this.dateHelper)
    this.initWithOptions(options)
    this.handleCellSelected = (cell, rowIndex, colIndex) => {
      if (!(this.helper instanceof SheetHelper)) return
      /// TODO: 这里需要转换成修改特定表的数据
      /// 1. 修改主表数据
      if (rowIndex >= this.headerRowCount && colIndex < this.helper.offset.ci) {
        const col = colIndex
        const row = rowIndex - this.headerRowCount
        const cell = this.helper.getGroupCellValue(row, col)
        this.sheet.trigger('custom-cell-selected', {
          isGroupCell: true,
          cell,
          colIndex,
          rowIndex,
          row,
          col
        })
      }

      /// 3. 修改关联表数据
      if (rowIndex >= this.headerRowCount && colIndex >= this.helper.offset.ci) {
        const col = colIndex - this.helper.offset.ci
        const row = rowIndex - this.headerRowCount
        const cell = this.helper.getCellValue(row, col)
        this.sheet.trigger('custom-cell-selected', {
          isCell: true,
          cell,
          colIndex,
          rowIndex,
          row,
          col
        })
      }
    }
    this.handleCellChange = (cell, rowIndex, colIndex) => {
      if (!(this.helper instanceof SheetHelper)) return
      this.defaultData.validations.validate(rowIndex, colIndex)
      /// TODO: 这里需要转换成修改特定表的数据
      /// 1. 修改主表数据
      if (rowIndex >= this.headerRowCount && colIndex < this.helper.offset.ci) {
        const col = colIndex
        const row = rowIndex - this.headerRowCount
        var flag = this.helper.updateGroupCellValue(row, col, cell)
        if (flag) {
          this.defaultData.setCellEditable(rowIndex, colIndex, true)
          this.defaultData.setCellStyle(rowIndex, colIndex, 0)
        } else {
          this.defaultData.setCellStyle(rowIndex, colIndex, undefined)
        }
      }

      /// 2. 修改关联表数据
      if (rowIndex >= this.headerRowCount && colIndex >= this.helper.offset.ci) {
        const col = colIndex - this.helper.offset.ci
        const row = rowIndex - this.headerRowCount
        console.log('你修改了数据' + cell)
        const flag = this.helper.updateCellValue(row, col, cell)
        if (flag) {
          this.defaultData.setCellStyle(rowIndex, colIndex, 0)
        } else {
          this.defaultData.setCellStyle(rowIndex, colIndex, undefined)
        }
        const ref = xy2expr(colIndex, rowIndex)
        this.defaultData.addCellValidator(ref, 'number')
      }

      this.defaultData.validations.validate(rowIndex, colIndex, cell)
    }

    this.handleCellsChange = () => {
      const { sri, sci, eri, eci } = this.defaultData.selector.range

      for (var rowIndex = sri; rowIndex <= eri; rowIndex++) {
        for (var colIndex = sci; colIndex <= eci; colIndex++) {
          var cell = this.defaultData.getCellText(rowIndex, colIndex)

          /// 1. 修改主表数据
          if (rowIndex >= this.headerRowCount && colIndex < this.helper.offset.ci) {
            const col = colIndex
            const row = rowIndex - this.headerRowCount
            var flag = this.helper.updateGroupCellValue(row, col, cell)
            if (flag) {
              this.defaultData.setCellEditable(rowIndex, colIndex, true)
              this.defaultData.setCellStyle(rowIndex, colIndex, 0)
            } else {
              this.defaultData.setCellStyle(rowIndex, colIndex, undefined)
            }
          }

          /// 2. 修改关联表数据
          if (rowIndex >= this.headerRowCount && colIndex >= this.helper.offset.ci) {
            const col = colIndex - this.helper.offset.ci
            const row = rowIndex - this.headerRowCount
            console.log('你修改了数据' + cell)
            const flag = this.helper.updateCellValue(row, col, cell)
            if (flag) {
              this.defaultData.setCellStyle(rowIndex, colIndex, 0)
            } else {
              this.defaultData.setCellStyle(rowIndex, colIndex, undefined)
            }
            const ref = xy2expr(colIndex, rowIndex)
            this.defaultData.addCellValidator(ref, 'number')
          }

          this.defaultData.validations.validate(rowIndex, colIndex, cell)
        }
      }
    }

    this.on('cells-edit', (evt) => {
      console.log('你批量修了数据')
      this.handleCellsChange()
    })

    this.on('cell-selected', (cell, rowIndex, colIndex) => {
      this.handleCellSelected(cell, rowIndex, colIndex)
    })
    this.on('cells-selected', (cell, parameters) => {

    })
    this.on('cell-edited', (cell, rowIndex, colIndex) => {
      this.handleCellChange(cell, rowIndex, colIndex)
    })

    this.renderDefaultSheet()
    this.reBindContextMenu()
  }
  /// 弹框选择过后 - 插入数据
  selectedRows (rows = [], rowIndex) {
    if (rows.length === 0) return
    rows = rows.map((item) => {
      item.rowId = getGuid()
      item.orderId = item.rowId
      item.material = item.oeb04
      item.itm_name = item.oeb06
      item.customer = item.oea03
      item.customer_name = item.oea032
      return item
    })
    const row = rowIndex - this.headerRowCount
    /// 1. 第一行替换
    this.helper.updateGroupValue(row, rows[0])
    /// 2. 第二行过后插入
    if (rows.length > 1) {
      this.helper.insertGroupRows(row, rows.slice(1))
    }
    this.renderDefaultSheet()
  }

  initWithOptions (options = {}) {
    this.editable = options.editable
    this.headerRowCount = options.headerRowCount || 2
    this.data = options.secondaryTableData || stocks
    this.helper = new SheetHelper({
      data: this.data,
      headerRowCount: this.headerRowCount
    })
  }

  resetData (options = {}) {
    this.initWithOptions(options)
    this.renderDefaultSheet()
  }

  mergeRange (range, rn = 3, cn = 1) {
    this.defaultData.mergeRange(range, rn, cn)
  }

  reRender () {
    if (!(this.helper instanceof SheetHelper)) return
    const groupHeaderColumnCount = this.helper.groupHelper.renderTable.length
    const headerColumnCount = this.helper.helper.dateHelper.dateList.length
    const groupRowCount = this.helper.groupHelper.groupIds.length

    const table = {
      row: groupRowCount + this.headerRowCount,
      column: groupHeaderColumnCount + headerColumnCount
    }
    /// 1. 渲染分组头部
    var merges = []
    for (let i = 0; i < groupHeaderColumnCount; i++) {
      const cell = this.helper.getGroupHeaderValue(i)
      this.renderCell(0, i, cell)
      merges.push(xy2expr(i, 0) + ':' + xy2expr(i, this.headerRowCount - 1))
    }

    /// 2. 渲染数据头部
    for (let i = 0; i < headerColumnCount; i++) {
      const ci = i + groupHeaderColumnCount
      const cell = this.helper.getHeaderValue(i)
      this.renderCell(0, ci, cell)
      // if (cell.isWeek) {
      //   merges.push(xy2expr(ci, 0) + ':' + xy2expr(ci, this.headerRowCount - 1))
      // } else {
        var date = new Date(cell.date)
        var day = date.getDay()
        this.renderCell(1, ci, {
          value: cell.isNew ? '' : '周' + numbers[(day + 7) % 7],
          editable: false,
          style: cell.style
        })
      // }
    }

    /// 3. 渲染分组表格
    for (let i = 0; i < groupHeaderColumnCount; i++) {
      for (let j = 0; j < groupRowCount; j++) {
        const cell = this.helper.getGroupCellValue(j, i)
        if (cell.align) {
          var cstyle = {}
          if (cell.style !== undefined) {
            cstyle = helper.cloneDeep(this.defaultData.styles[cell.style])
          }
          cstyle.align = cell.align
          cell.style = this.defaultData.addStyle(cstyle)
        }
        if (cell.valueRender) {
          const value = cell.valueRender({
            ri: j + this.headerRowCount,
            ci: i,
            value: cell.value,
            row: table.row,
            column: table.column,
            dateHelper: this.helper.helper.dateHelper
          })
          this.renderCell(j + this.headerRowCount, i, {
            ...cell,
            value: value
          })
        } else {
          this.renderCell(j + this.headerRowCount, i, cell)
        }
      }
    }

    /// 4. 渲染数据表格
    this.helper.helper.getDataMap()
    for (let i = 0; i < headerColumnCount; i++) {
      for (let j = 0; j < groupRowCount; j++) {
        const cell = this.helper.getCellValue(j, i)
        cell.validator = 'number'
        this.renderCell(j + this.headerRowCount, i + groupHeaderColumnCount, cell)
      }
    }

    this.defaultData.merges.setData(merges)
    this.defaultData.merges._.map((range) => {
      this.mergeRange(range, this.headerRowCount)
    })
    this.sheet.resetData(this.defaultData)
    super.reRender()
  }

  renderCell (ri, ci, { value, editable, style, validator, width, clickable }) {
    this.defaultData.renderCell(ri, ci, { value, editable, style, validator, width, clickable })
  }

  reBindContextMenu () {
    /// 重新绑定 context
    var children = this.sheet.contextMenu.el.children()
    children.forEach(item => {
      item.classList.add('hidden')
    })
    this.sheet.contextMenu.menuItems = buildMenu.call(this.sheet.contextMenu)
    this.sheet.contextMenu.el.children(...this.sheet.contextMenu.menuItems)
    this.sheet.contextMenu.itemClick = (type) => {
      console.log(type, this.defaultData.selector.range)
      /// TODO: 这里做插入数据处理，应该先弹框 然后做数据插入
      /// 如果是主表数据插入，则直接主表数据插入一条
      /// 如果是关联表数据插入，则需要插入一条默认数据

      /// 以下是测试操作
      if (type === 'new-bill') {
        this.sheet.trigger('new-bill')
      }

      if (!(this.helper instanceof SheetHelper)) return
      if (type === 'insert-up-row') {
        const { sri } = this.defaultData.selector.range
        const { ri } = this.helper.offset

        const rowIndex = sri - ri

        this.helper.insertRow(rowIndex < 0 ? 0 : rowIndex, 'prev')
        this.renderDefaultSheet()
      }

      if (type === 'insert-down-row') {
        const { sri } = this.defaultData.selector.range
        const { ri } = this.helper.offset
        const rowIndex = sri - ri
        this.helper.insertRow(rowIndex < 0 ? 0 : rowIndex, 'next')
        this.renderDefaultSheet()
      }

      if (type === 'delete-row') {
        const { sri, eri } = this.defaultData.selector.range
        for (var rowIndex = eri; rowIndex >= sri; rowIndex--) {
          this.helper.deleteRow(rowIndex)
        }
        this.renderDefaultSheet()
      }
    }
    this.sheet.contextMenu.setMode = (mode) => {}
  }

  renderDefaultSheet (name, active = true) {
    const n = name || `sheet`
    const rowCount = this.helper.rowCount
    const colCount = this.helper.columnCount
    if (this.defaultData && (this.rowCount === rowCount && this.colCount === colCount)) {
      this.reRender()
      return
    }
    const d = new CustomDataProxy(n, {
      ...this.options,
      row: {
        len: rowCount
      },
      col: {
        len: colCount
      }
    })
    d.change = (...args) => {
      this.sheet.trigger('change', ...args)
    }
    this.rowCount = rowCount
    this.colCount = colCount
    this.data = d
    this.defaultData = d
    this.datas = [d]
    if (this.bottombar !== null) {
      this.bottombar.renameItem(0, n)
    }
    this.sheet.resetData(d)
    this.reRender()
    this.sheet.freeze(
      this.headerRowCount,
      4
      // this.helper.groupHelper.columnCount
    )
    return d
  }
}

export default CustomSpreadsheet
